﻿using SimpleInjector;
using Sustainalytics.BusinessResearchProductStates.Entities.ResearchState;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.Synchronization.Interface;
using Sustainalytics.Entities;
using Sustainalytics.MongoDB.Extensions;
using System.Collections.Generic;
using System.Configuration.Abstractions;
using System;
using Sustainalytics.Entities.Governance;
using Sustainalytics.CDDB.DataConnector;

namespace Sustainalytics.Governance.Synchronization
{
    public static class SimpleInjectorConfig
    {
        public static Dictionary<string, string> ConnectionStrings { get; set; }

        public static Container Register(ILogger logger, Dictionary<string, string> gaConnectionStrings)
        {
            var container = new Container();

            if (gaConnectionStrings == null || gaConnectionStrings.Count == 0)
                throw new ArgumentException("Connection strings must be provided in order to register!");

            container.RegisterCollections(gaConnectionStrings);

            container.RegisterMisc(logger);

            container.Register<GovernanceSync>();

            container.Register<CorporateGovernanceResearchImport>();

            container.Verify();

            return container;
        }


        private static void RegisterCollections(this Container container, Dictionary<string, string> gaConnectionStrings)
        {
            if (!gaConnectionStrings.TryGetValue("ClientDW", out string clientDwConnectionString))
            {
                throw new ArgumentException("No connection string found for ClientDW!");
            }

            if (!gaConnectionStrings.TryGetValue("GovernanceDW", out string governanceDwConnectionString))
            {
                throw new ArgumentException("No connection string found for GovernanceDW!");
            }

            if (!gaConnectionStrings.TryGetValue("GovernanceInputFile", out string governanceInputFileConnectionString))
            {
                throw new ArgumentException("No connection string found for GovernanceInputFile!");
            }

            container.Register(() => MongoFactory.GetCollectionFromDatabase<CorporateData>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<CompanyProfileResearchState>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernanceCompanyProfile>(governanceDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernanceRegion>(governanceDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernanceIndicatorTemplate>(governanceDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernanceIndicator>(governanceDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernanceSource>(governanceDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernanceIssue>(governanceDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernanceComputationResult>(governanceDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernanceAssessmentThreshold>(governanceDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernanceInsightInputFile>(governanceInputFileConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<SharedEntities.CorporateGovernanceResearch.CorporateGovernanceResearchProfile>(governanceDwConnectionString));
        }

        private static void RegisterMisc(this Container container, ILogger logger)
        {
            container.Register(() => logger, Lifestyle.Singleton);
            container.RegisterSingleton(() => ConfigurationManager.Instance.AppSettings);
            container.RegisterSingleton<BackOfficeAppSettings>();

            container.RegisterSingleton(() => new CorporateDataRepository(container.GetInstance<BackOfficeAppSettings>().ThriftServer,
                                                                            container.GetInstance<BackOfficeAppSettings>().ThriftPort,
                                                                            container.GetInstance<BackOfficeAppSettings>().HbaseTablePrefix,
                                                                            container.GetInstance<BackOfficeAppSettings>().HiveConnectionString));


            container.RegisterSingleton(() => new CorporateGovernanceDataProvider.CorporateGovernanceDataProvider(new Ai.HbaseRepository.HbaseConfiguration
            {
                ThriftServerAddress = container.GetInstance<BackOfficeAppSettings>().ThriftServer,
                ThriftPort = container.GetInstance<BackOfficeAppSettings>().ThriftPort,
                TablePrefix = container.GetInstance<BackOfficeAppSettings>().HbaseTablePrefix,
            }));

            container.Register<CorporateGovernanceAssessmentThresholdsQuery>();
            container.Register<CorporateGovernanceResearchProfileQuery>();
            container.Register<CorporateDataQuery>();
            container.RegisterSingleton(() => new SaveEntitiesAsync(container.GetInstance<MongoCollectionFactory>(), 
                                                                    logger, 
                                                                    ConfigurationManager.Instance.AppSettings.AppSetting("InsertManyBatchSize", () => 500)));
        }
    }
}
